/**
 * 全局网络请求工具类
 * 封装wx.request，统一处理请求、响应和错误
 * 支持自动显示/隐藏loading
 */

// 服务器基础URL，根据实际环境配置
const BASE_URL = 'http://192.168.2.103:8080/signApi';
const APP_ID = 'wxce1f4e2dc81832ac';
const IMG_URL = 'https://xueshanbanlv-1364336512.cos.ap-beijing.myqcloud.com/';
// 请求超时时间（毫秒）
const TIMEOUT = 15000;

// 默认请求头
const DEFAULT_HEADER = {
  'Content-Type': 'application/json'
};

// 正在进行的请求数量，用于控制loading的显示和隐藏
let requestCount = 0;

/**
 * 显示loading
 * @param {String} title loading提示文字
 */
const showLoading = (title = '加载中...') => {
  if (requestCount === 0) {
    wx.showLoading({
      title: title,
      mask: true
    });
  }
  requestCount++;
};

/**
 * 隐藏loading
 */
const hideLoading = () => {
  requestCount--;
  if (requestCount === 0) {
    wx.hideLoading();
  }
};

/**
 * 处理请求错误
 * @param {Object} error 错误对象
 * @param {Function} reject Promise的reject函数
 */
const handleError = (error, reject) => {
  // 处理错误信息
  let errorMsg = '';
  
  if (error && error.errMsg) {
    if (error.errMsg.includes('timeout')) {
      errorMsg = '请求超时，请检查网络';
    } else {
      errorMsg = '网络开小差了，请稍后重试';
    }
  } else if (typeof error === 'string') {
    errorMsg = error;
  } else {
    errorMsg = '请求失败，请稍后重试';
  }
  
  // 显示错误提示
  wx.showToast({
    title: errorMsg,
    icon: 'none',
    duration: 2000
  });
  
  // 返回错误
  reject(error);
};

/**
 * 发送请求的基础方法
 * @param {Object} options 请求配置
 * @returns {Promise} Promise对象
 */
const request = (options = {}) => {
  // 获取openId作为凭证
  const openId = wx.getStorageSync('openId');
  
  // 合并请求头
  const header = {
    ...DEFAULT_HEADER,
    ...options.header
  };
  
  // 如果有openId，添加到请求头
  if (openId) {
    header['Authorization'] = `${openId}`;
  }
  
  // 是否显示loading
  const showLoadingFlag = options.showLoading !== false;
  
  // 完整的请求URL
  const url = /^(http|https):\/\//.test(options.url) 
    ? options.url 
    : BASE_URL + options.url;
  
  // 显示loading
  if (showLoadingFlag) {
    showLoading(options.loadingText);
  }
  
  // 返回Promise
  return new Promise((resolve, reject) => {
    wx.request({
      url: url,
      data: options.data || {},
      method: options.method || 'GET',
      header: header,
      timeout: options.timeout || TIMEOUT,
      success: (res) => {
        // 自动从header中获取并存储openId (如果后端通过header返回)
        const openIdFromHeader = res.header.Authorization || res.header.authorization;
        if (openIdFromHeader) {
          console.log('[Request] 在响应头中找到凭证(openId)，准备存储:', openIdFromHeader);
          wx.setStorageSync('openId', openIdFromHeader);
        }

        // 自定义状态码处理
        if (res.statusCode === 200) {
          // 根据业务状态码处理
          const result = res.data;
          if (result && result.code === 200) {
            // 自动从body中获取并存储openId（仅在允许的情况下）
            if (result.data && result.data.openId && options.autoSaveOpenId !== false) {
              console.log('[Request] 在响应体中找到openId，准备存储:', result.data.openId);
              wx.setStorageSync('openId', result.data.openId);
            }
            resolve(result.data);
          } else {
            // 业务错误处理
            const errorMsg = result.msg || '请求失败';
            wx.showToast({
              title: errorMsg,
              icon: 'none',
              duration: 2000
            });
            reject({ code: result.code, msg: errorMsg });
          }
        } else if (res.statusCode === 401) {
          // 未授权，需要登录
          wx.showToast({
            title: '请先登录',
            icon: 'none',
            duration: 2000
          });
          
          reject({ code: 401, msg: '请先登录' });
        } else {
          // 其他HTTP错误
          handleError({ errMsg: `HTTP错误: ${res.statusCode}` }, reject);
        }
      },
      fail: (error) => {
        handleError(error, reject);
      },
      complete: () => {
        // 隐藏loading
        if (showLoadingFlag) {
          hideLoading();
        }
      }
    });
  });
};

/**
 * GET请求
 * @param {String} url 请求地址
 * @param {Object} data 请求参数
 * @param {Object} options 其他配置
 * @returns {Promise} Promise对象
 */
const get = (url, data = {}, options = {}) => {
  return request({
    url,
    data,
    method: 'GET',
    ...options
  });
};

/**
 * POST请求
 * @param {String} url 请求地址
 * @param {Object} data 请求参数
 * @param {Object} options 其他配置
 * @returns {Promise} Promise对象
 */
const post = (url, data = {}, options = {}) => {
  return request({
    url,
    data,
    method: 'POST',
    ...options
  });
};

/**
 * PUT请求
 * @param {String} url 请求地址
 * @param {Object} data 请求参数
 * @param {Object} options 其他配置
 * @returns {Promise} Promise对象
 */
const put = (url, data = {}, options = {}) => {
  return request({
    url,
    data,
    method: 'PUT',
    ...options
  });
};

/**
 * DELETE请求
 * @param {String} url 请求地址
 * @param {Object} data 请求参数
 * @param {Object} options 其他配置
 * @returns {Promise} Promise对象
 */
const del = (url, data = {}, options = {}) => {
  return request({
    url,
    data,
    method: 'DELETE',
    ...options
  });
};

/**
 * 上传文件
 * @param {String} url 上传地址
 * @param {String} filePath 文件路径
 * @param {String} name 文件对应的key
 * @param {Object} formData 其他表单数据
 * @param {Object} options 其他配置
 * @returns {Promise} Promise对象
 */
const uploadFile = (url, filePath, name = 'file', formData = {}, options = {}) => {
  // 获取openId作为凭证
  const openId = wx.getStorageSync('openId');
  
  // 完整的请求URL
  const fullUrl = /^(http|https):\/\//.test(url) ? url : BASE_URL + url;
  
  // 是否显示loading
  const showLoadingFlag = options.showLoading !== false;
  
  // 显示loading
  if (showLoadingFlag) {
    showLoading(options.loadingText || '上传中...');
  }
  
  // 准备请求头
  const header = {
    'Content-Type': 'multipart/form-data',
    ...options.header
  };
  
  // 如果有openId，添加到请求头
  if (openId) {
    header['Authorization'] = `${openId}`;
  }
  
  return new Promise((resolve, reject) => {
    wx.uploadFile({
      url: fullUrl,
      filePath: filePath,
      name: name,
      formData: formData,
      header: header,
      success: (res) => {
        if (res.statusCode === 200) {
          // 自动从header中获取并存储openId
          const openIdFromHeader = res.header.Authorization || res.header.authorization;
          if (openIdFromHeader) {
            console.log('[Request-Upload] 在响应头中找到凭证(openId)，准备存储:', openIdFromHeader);
            wx.setStorageSync('openId', openIdFromHeader);
          }

          // 注意：uploadFile的返回数据是字符串，需要手动转换
          let data;
          try {
            data = JSON.parse(res.data);
          } catch (e) {
            handleError({ errMsg: '服务器返回数据格式错误' }, reject);
            return;
          }
          
          if (data && data.code === 200) {
            // 自动从body中获取并存储openId
            if (data.data && data.data.openId) {
              console.log('[Request-Upload] 在响应体中找到openId，准备存储:', data.data.openId);
              wx.setStorageSync('openId', data.data.openId);
            }
            resolve(data.data);
          } else {
            const errorMsg = data.msg || '上传失败';
            wx.showToast({
              title: errorMsg,
              icon: 'none',
              duration: 2000
            });
            reject({ code: data.code, msg: errorMsg });
          }
        } else {
          handleError({ errMsg: `HTTP错误: ${res.statusCode}` }, reject);
        }
      },
      fail: (error) => {
        handleError(error, reject);
      },
      complete: () => {
        if (showLoadingFlag) {
          hideLoading();
        }
      }
    });
  });
};

// 导出接口
module.exports = {
  request,
  get,
  post,
  put,
  del,
  uploadFile,
  BASE_URL,
  APP_ID,
  IMG_URL
}; 